Component Objects: C++ Nested Classes

The next example shows how the same object is declared and initialized using the C++ nested class approach. As in the C example, the nested class declaration includes one data structure for each interface and four private data members: an object-level reference count, two interface pointers, and a pointer to the enclosing object. The private implementations of the IUnknown1NEM0LU methods are called by the implementations declared for the derived interfaces. For each interface implementation, there is a structure containing a public constructor and destructor, private declarations of the interface methods, a private pointer to CObj, and an interface-level reference counter for debugging purposes. To allow the nested interface classes to access the private members of the outer class, each interface class is made a friend of the outer class.

The benefits of implementing with C++ nested classes lie in the ability to include initialization code and method implementation inline. However, inline declaration is for the convenience of illustration and is not required.

class  CObj 

 

private:

  ULONG          m_ObjRefCount;

  LPSTORAGE      m_pStg;

  LPOLEOBJECT    m_pOleObj;

  CDOC    *      m_pCDoc;

 

public:

  CObj();

  ~CObj();

 

  struct CUnknown : IUnknown

  private:

  ULONG          m_RefCount;

  CObj  *        m_pCObj;

 

  public:

  CUnknown(CObj (pCObj)

  {  m_pCObj = pCObj; m_RefCount = 0; }

  HRESULT QueryInterface(REFIID riid, LPVOID  * ppvObj)

  ULONG AddRef(void) {  return ++m_ObjRefCount; }

  ULONG Release(void);

}

friend CUnknown;

CUnknown m_Unknown;

 

struct InterfaceA : InterfaceA

  private:

  ULONG          m_RefCount;

  CObj  *        m_pCObj;

 

  public:

  CInterfaceA(CObj *pCObj)

  {  m_pCObj = pCObj; m_RefCount = 0; }

  HRESULT QueryInterface(REFIID riid, LPVOID  * ppvObj)

  ULONG AddRef(void) {  return ++m_ObjRefCount; }

  ULONG Release(void);

  HRESULT MethodA1(LPVOID  * ppvObj);

  HRESULT MethodA2(DWORD dwArg);

}

friend CInterfaceA;

CInterfaceA m_InterfaceA;

 

struct InterfaceB : InterfaceB

  private:

  ULONG          m_RefCount;

  CObj  *        m_pCObj;

 

  public:

  CInterfaceB(CObj *pCObj)

  {  m_pCObj = pCObj; m_RefCount = 0; }

  HRESULT QueryInterface(REFIID riid, LPVOID  * ppvObj)

  ULONG AddRef(void) {  return ++m_ObjRefCount; }

  ULONG Release(void);

  HRESULT MethodB1(void);

  HRESULT MethodB2(DWORD dwArg1, DWORD dwArg2);

}

friend CInterfaceB;

CInterfaceB m_InterfaceB;